/*
 * PhotonRTOS础光实时操作系统 -- 外设测试代码
 *
 * Copyright (C) 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Yili Zhang <s-zhangyili@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include "../utest.h"
#include <Os.h>

extern int8_t peripheral_test[];
#define UART0 2
#define UART0_ADDRESS peripheral_test
#define UART0_SIZE 0x1000

TEST(ReadPeripheral8)
{
	VAR(uint8, AUTOMATIC) u8_value;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	st = ReadPeripheral8(CONFIG_AUTOSAR_MAX_PERIPHERAL, (uint8 *)UART0_ADDRESS, &u8_value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	st = ReadPeripheral8(UART0, (uint8 *)(UART0_ADDRESS - 1), &u8_value);
	ASSERT_EQ(st, E_OS_VALUE);

	st = ReadPeripheral8(UART0, (uint8 *)(UART0_ADDRESS + UART0_SIZE), &u8_value);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	u8_value = 0;
	*((uint8 *)UART0_ADDRESS) = 0xaa;
	st = ReadPeripheral8(UART0, (uint8 *)UART0_ADDRESS, &u8_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(u8_value, 0xaa);

	u8_value = 0;
	*((uint8 *)(UART0_ADDRESS + UART0_SIZE - 1)) = 0xaa;
	st = ReadPeripheral8(UART0, (uint8 *)(UART0_ADDRESS + UART0_SIZE - 1), &u8_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(u8_value, 0xaa);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(ReadPeripheral16)
{
	VAR(uint16, AUTOMATIC) u16_value;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	st = ReadPeripheral16(CONFIG_AUTOSAR_MAX_PERIPHERAL, (uint16 *)UART0_ADDRESS, &u16_value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	st = ReadPeripheral16(UART0, (uint16 *)(UART0_ADDRESS - 1), &u16_value);
	ASSERT_EQ(st, E_OS_VALUE);

	st = ReadPeripheral16(UART0, (uint16 *)(UART0_ADDRESS + UART0_SIZE), &u16_value);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	u16_value = 0;
	*((uint16 *)UART0_ADDRESS) = 0xaaaa;
	st = ReadPeripheral16(UART0, (uint16 *)UART0_ADDRESS, &u16_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(u16_value, 0xaaaa);

	u16_value = 0;
	*((uint16 *)(UART0_ADDRESS + UART0_SIZE - 2)) = 0xaaaa;
	st = ReadPeripheral16(UART0, (uint16 *)(UART0_ADDRESS + UART0_SIZE - 2), &u16_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(u16_value, 0xaaaa);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(ReadPeripheral32)
{
	VAR(uint32, AUTOMATIC) u32_value;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	st = ReadPeripheral32(CONFIG_AUTOSAR_MAX_PERIPHERAL, (uint32 *)UART0_ADDRESS, &u32_value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	st = ReadPeripheral32(UART0, (uint32 *)(UART0_ADDRESS - 1), &u32_value);
	ASSERT_EQ(st, E_OS_VALUE);

	st = ReadPeripheral32(UART0, (uint32 *)(UART0_ADDRESS + UART0_SIZE), &u32_value);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	u32_value = 0;
	*((uint32 *)UART0_ADDRESS) = 0xaaaaaaaa;
	st = ReadPeripheral32(UART0, (uint32 *)UART0_ADDRESS, &u32_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(u32_value, 0xaaaaaaaa);

	u32_value = 0;
	*((uint32 *)(UART0_ADDRESS + UART0_SIZE - 4)) = 0xaaaaaaaa;
	st = ReadPeripheral32(UART0, (uint32 *)(UART0_ADDRESS + UART0_SIZE - 4), &u32_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(u32_value, 0xaaaaaaaa);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(WritePeripheral8)
{
	VAR(uint8, AUTOMATIC) u8_value;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	u8_value = 0x55;
	st = WritePeripheral8(CONFIG_AUTOSAR_MAX_PERIPHERAL, (uint8 *)UART0_ADDRESS, u8_value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	u8_value = 0x55;
	st = WritePeripheral8(UART0, (uint8 *)(UART0_ADDRESS - 1), u8_value);
	ASSERT_EQ(st, E_OS_VALUE);

	st = WritePeripheral8(UART0, (uint8 *)(UART0_ADDRESS + UART0_SIZE), u8_value);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	*((uint8 *)UART0_ADDRESS) = 0;
	u8_value = 0x55;
	st = WritePeripheral8(UART0, (uint8 *)UART0_ADDRESS, u8_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint8 *)UART0_ADDRESS), 0x55);

	*((uint8 *)(UART0_ADDRESS + UART0_SIZE - 1)) = 0;
	u8_value = 0x55;
	st = WritePeripheral8(UART0, (uint8 *)(UART0_ADDRESS + UART0_SIZE - 1), u8_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint8 *)(UART0_ADDRESS + UART0_SIZE - 1)), 0x55);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(WritePeripheral16)
{
	VAR(uint16, AUTOMATIC) u16_value;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	u16_value = 0x5555;
	st = WritePeripheral16(CONFIG_AUTOSAR_MAX_PERIPHERAL, (uint16 *)UART0_ADDRESS, u16_value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	u16_value = 0x5555;
	st = WritePeripheral16(UART0, (uint16 *)(UART0_ADDRESS - 1), u16_value);
	ASSERT_EQ(st, E_OS_VALUE);

	st = WritePeripheral16(UART0, (uint16 *)(UART0_ADDRESS + UART0_SIZE), u16_value);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	*((uint16 *)UART0_ADDRESS) = 0;
	u16_value = 0x5555;
	st = WritePeripheral16(UART0, (uint16 *)UART0_ADDRESS, u16_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint16 *)UART0_ADDRESS), 0x5555);

	*((uint16 *)(UART0_ADDRESS + UART0_SIZE - 2)) = 0;
	u16_value = 0x5555;
	st = WritePeripheral16(UART0, (uint16 *)(UART0_ADDRESS + UART0_SIZE - 2), u16_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint16 *)(UART0_ADDRESS + UART0_SIZE - 2)), 0x5555);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(WritePeripheral32)
{
	VAR(StatusType, AUTOMATIC) st;
	VAR(uint32, AUTOMATIC) u32_value;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	u32_value = 0x55555555;
	st = WritePeripheral32(CONFIG_AUTOSAR_MAX_PERIPHERAL, (uint32 *)UART0_ADDRESS, u32_value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	u32_value = 0x55555555;
	st = WritePeripheral32(UART0, (uint32 *)(UART0_ADDRESS - 1), u32_value);
	ASSERT_EQ(st, E_OS_VALUE);

	st = WritePeripheral32(UART0, (uint32 *)(UART0_ADDRESS + UART0_SIZE), u32_value);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	*((uint32 *)UART0_ADDRESS) = 0;
	u32_value = 0x55555555;
	st = WritePeripheral32(UART0, (uint32 *)UART0_ADDRESS, u32_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint32 *)UART0_ADDRESS), 0x55555555);

	*((uint32 *)(UART0_ADDRESS + UART0_SIZE - 4)) = 0;
	u32_value = 0x55555555;
	st = WritePeripheral32(UART0, (uint32 *)(UART0_ADDRESS + UART0_SIZE - 4), u32_value);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint32 *)(UART0_ADDRESS + UART0_SIZE - 4)),
		0x55555555);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(ModifyPeripheral8)
{
	VAR(uint8, AUTOMATIC) u8_clear_mask = 0;
	VAR(uint8, AUTOMATIC) u8_set_mask = 0;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	st = ModifyPeripheral8(CONFIG_AUTOSAR_MAX_PERIPHERAL,
		(uint8 *)UART0_ADDRESS, u8_clear_mask, u8_set_mask);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	st = ModifyPeripheral8(UART0, (uint8 *)(UART0_ADDRESS - 1), u8_clear_mask, u8_set_mask);
	ASSERT_EQ(st, E_OS_VALUE);

	st = ModifyPeripheral8(UART0, (uint8 *)(UART0_ADDRESS + UART0_SIZE),
		u8_clear_mask, u8_set_mask);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	*((uint8 *)UART0_ADDRESS) =	0xf0;
	u8_clear_mask =			0xcc;
	u8_set_mask =			0xaa;
	st = ModifyPeripheral8(UART0, (uint8 *)UART0_ADDRESS, u8_clear_mask, u8_set_mask);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint8 *)UART0_ADDRESS), 0xea);

	*((uint8 *)(UART0_ADDRESS + UART0_SIZE - 1)) =	0xf0;
	u8_clear_mask =					0xcc;
	u8_set_mask =					0xaa;
	st = ModifyPeripheral8(UART0, (uint8 *)(UART0_ADDRESS + UART0_SIZE - 1),
		u8_clear_mask, u8_set_mask);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint8 *)(UART0_ADDRESS + UART0_SIZE - 1)), 0xea);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(ModifyPeripheral16)
{
	VAR(uint16, AUTOMATIC) u16_clear_mask = 0;
	VAR(uint16, AUTOMATIC) u16_set_mask = 0;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	st = ModifyPeripheral16(CONFIG_AUTOSAR_MAX_PERIPHERAL,
		(uint16 *)UART0_ADDRESS, u16_clear_mask, u16_set_mask);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	st = ModifyPeripheral16(UART0, (uint16 *)(UART0_ADDRESS - 1), u16_clear_mask, u16_set_mask);
	ASSERT_EQ(st, E_OS_VALUE);

	st = ModifyPeripheral16(UART0, (uint16 *)(UART0_ADDRESS + UART0_SIZE),
		u16_clear_mask, u16_set_mask);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	*((uint16 *)UART0_ADDRESS) =	0xf0f0;
	u16_clear_mask =		0xcccc;
	u16_set_mask =			0xaaaa;
	st = ModifyPeripheral16(UART0, (uint16 *)UART0_ADDRESS, u16_clear_mask, u16_set_mask);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint16 *)UART0_ADDRESS), 0xeaea);

	*((uint16 *)(UART0_ADDRESS + UART0_SIZE - 2)) =	0xf0f0;
	u16_clear_mask =				0xcccc;
	u16_set_mask =					0xaaaa;
	st = ModifyPeripheral16(UART0, (uint16 *)(UART0_ADDRESS + UART0_SIZE - 2),
		u16_clear_mask, u16_set_mask);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint16 *)(UART0_ADDRESS + UART0_SIZE - 2)), 0xeaea);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}

TEST(ModifyPeripheral32)
{
	VAR(uint32, AUTOMATIC) u32_clear_mask = 0;
	VAR(uint32, AUTOMATIC) u32_set_mask = 0;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
	 */
	st = ModifyPeripheral32(CONFIG_AUTOSAR_MAX_PERIPHERAL,
		(uint32 *)UART0_ADDRESS, u32_clear_mask, u32_set_mask);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * E_OS_VALUE 地址不属于给定区域（扩展状态）
	 */
	st = ModifyPeripheral32(UART0, (uint32 *)(UART0_ADDRESS - 1), u32_clear_mask, u32_set_mask);
	ASSERT_EQ(st, E_OS_VALUE);

	st = ModifyPeripheral32(UART0, (uint32 *)(UART0_ADDRESS + UART0_SIZE),
		u32_clear_mask, u32_set_mask);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
	 */
#endif

	/**
	 * E_OK 无错误
	 */
	*((uint32 *)UART0_ADDRESS) =	0xf0f0f0f0;
	u32_clear_mask =		0xcccccccc;
	u32_set_mask =			0xaaaaaaaa;
	st = ModifyPeripheral32(UART0, (uint32 *)UART0_ADDRESS, u32_clear_mask, u32_set_mask);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint32 *)UART0_ADDRESS), 0xeaeaeaea);

	*((uint32 *)(UART0_ADDRESS + UART0_SIZE - 4)) =	0xf0f0f0f0;
	u32_clear_mask =				0xcccccccc;
	u32_set_mask =					0xaaaaaaaa;
	st = ModifyPeripheral32(UART0, (uint32 *)(UART0_ADDRESS + UART0_SIZE - 4),
		u32_clear_mask, u32_set_mask);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(*((uint32 *)(UART0_ADDRESS + UART0_SIZE - 4)),
		0xeaeaeaea);

	/**
	 * E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
	 */
}


TEST_SUIT(Peripheral)
{
	UTEST_CASE(ReadPeripheral8);
	UTEST_CASE(ReadPeripheral16);
	UTEST_CASE(ReadPeripheral32);
	UTEST_CASE(WritePeripheral8);
	UTEST_CASE(WritePeripheral16);
	UTEST_CASE(WritePeripheral32);
	UTEST_CASE(ModifyPeripheral8);
	UTEST_CASE(ModifyPeripheral16);
	UTEST_CASE(ModifyPeripheral32);
}

